require"redcell_wrapper"
local rc=redcell_wrapper
local _M={}

--print(rc)
for k,v in pairs(rc) do
	print(k,v)
end



local function dumpstring(str)
	local l=str:len()
	for k,v in ipairs{str:byte(1,l)} do
		io.write(string.format("0x%X ",v))
	end
	print""
end


local sw=rc.StringWriter()
sw:putString("xxx")
sw:putEnd()
local sr=rc.StringReader(sw:str())


dumpstring(sw:str())


print(sr:getFlag())
print(sr:getString())


local floor=math.floor

local function isint(v)
	return floor(v)==v
end

_M.importKey=function(key) 
	if type(key)=="number" then
		if isint(key) then
			return key
		else
			return nil,"Error! The type of key cannot be a float."
		end		
	elseif type(key)=="string" then 		
		return key
	else
		return nil,"Error! The type of key must be int or string."
	end
end


_M.importValue=function(v)
	if type(v) == "number" or type(v)=="string" or type(v)=="table" or type(v)=="nil" then
		return v
	else
		return nil,"Error! The type of value must be int or float or double or string or table or nil."
	end
end

local merge
local function merge(dst,src)
	for k,v in pairs(src) do
		if type(v)=="table" then
			if type(dst[k])=="table" then 
				merge(dst[k],v)
			else
				dst[k]=v
			end
		else
			dst[k]=v
		end	
	end
end
_M.merge=merge

INDENT = "    "
local function dump(tab,lv)
	if not lv then lv=0 end
    prefix = INDENT 
    innerprefix = prefix .. INDENT
    res = '{\n'
    expkey = 0
    for k, v in pairs(tab) do
        ik = importKey(k)
        iv = importValue(v)
	if type(ik)=="string" then
		if ik == expkey then
		        res = res .. innerprefix .. tostring(ik) .. '  '
		else	
			res = res .. innerprefix .. tostring(ik) .. '. '
		end
	end
        if type(iv)=='nil' then
            res = res .. 'NIL'
        elseif isint(iv) then
            res = res + 'INT '.. iv
        elseif type(iv)=='number' then
            res =res.. 'REAL ' .. iv
        elseif type(iv)=='string' then
            res =res.. 'STR ' .. iv
        elseif type(iv)=="table" then
            res =res.. dump(iv, lv + 1)
	end
        res =res..'\n'
	if isint(ik) then
        	expkey = ik .. 1
	else
		expkey = 0
	end
    end
    return res .. prefix .. '}'
end
_M.dump=dump

local function writeItem(buf, item)
	ii=importValue(item)
	
	if type(ii)=='nil' then
		buf:putNil()
        elseif isint(ii) then
		buf:putInteger(ii)
	elseif type(ii)=='number' then
	        buf:putReal(ii)
	elseif type(ii)=="string" then
	        buf.putString(ii)
	elseif type(ii)=="table" then
	        buf:putSub()
       		writeTable(buf, ii)
	end 
end

local function writeTable(buf,tab)
	local expkey=0
	for k,v in pairs(tab) do
		local ik=importKey(k)
		local iv=importValue(v)
		if isint(ik) then
			local keyinc = ik-expkey
			if keyinc>0 then
				buf:putKeySkip(keyinc)				
			end
			writeItem(buf,iv)
			expkey=expkey+1
		else
			buf:putStrKey(ik)
			writeItem(buf,iv)
		end
	end
	buf:putEnd();
end



local function pack(tab)
	buf=rc.StringWriter()
	WriteTable(buf,tab)
	return buf:str()
end



local function readItem(buf,tab,flag,key)
	print(flag)
	if flag == rc.F_NIL then
		tab[key]=nil
	elseif flag == rc.F_FALSE then
		tab[key]=rc.F_FALSE
	elseif flag == rc.F_TRUE then
		tab[key]=rc.F_TRUE
	elseif flag == rc.F_POS then
		tab[key]=buf.getInteger(0)
	elseif flag == rc.F_NEG then
		tab[key]=buf.getInteger(-1)
	elseif flag == rc.F_FLOAT then 
		tab[key]=rc.getFloat()
	end




end





return _M






